package cluedo.gui;

import java.awt.EventQueue;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import java.awt.GridLayout;
import javax.swing.DefaultListModel;
import javax.swing.JScrollPane;
import javax.swing.JList;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Rectangle;

import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Map;

import javax.swing.ListSelectionModel;
import cluedo.Player;
import javax.swing.JTextPane;
import javax.swing.JTextField;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.OceanTheme;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.plaf.ColorUIResource;

import common.CommonConstants;
import common.Logger;

/** 
 * Questa classe avvia Cluedo e lancia una finestra per la gestione dei 
 * preparativi di una partita 
 */
public class CluedoStart {

	/**
	 * Il player locale
	 */
	private Player myPlayer=null;
	/**
	 * La finestra di registrazione (aka finestra di selezione dei gruppi)
	 */
	private JFrame frame;
	/**
	 * Lista dei nomi dei gruppi di gioco
	 */
	private DefaultListModel groupListModel;
	/**
	 * Lista dei nomi degli altri player del gruppo di gioco di cui il player fa parte
	 */
	private DefaultListModel memberListModel;
	
	// pannello dei gruppi
	private JList groupList;
	private JButton btnCreateGroup;
	private JButton btnJoinGroup;
	// pannello dei membri del gruppo
	private JLabel membersLabel;
	private JList memberList;
	private JButton btnLeaveGroup;
	private JButton btnStartPlay;
	// pannello di chat
	private JTextPane textChatPane;
	private JTextField txtInputChat;
	private JButton btnSendChatMsg;

	/**
	 * Richiama testMain() o cluedoMain() a seconda del numero di argomenti
	 * @param args
	 */
	public static void main(String[] args){
		if (args.length==1) {
			cluedoMain(args);
		} else if (args.length==3) {
			testMain(args);
		} else {
			System.out.println("Passami 1 o 3 argomenti");
		}
	}
	
	/**
	 * Questo e' il metodo main() di test
	 *  
	 * I player devono chiamarsi "a", "b", "c", "d", "e", "f".
	 * 
	 * Esempi di sintassi:
	 * CluedoStart localhost 3 a
	 * CluedoStart localhost 3 b
	 * CluedoStart localhost 3 c
	 * 
	 * Altro esempio:
	 * CluedoStart localhost 5 a
	 * CluedoStart localhost 5 b
	 * CluedoStart localhost 5 c
	 * CluedoStart localhost 5 d
	 * CluedoStart localhost 5 e
	 * 
	 * Il numero 3 indica che si vuole lanciare 3 istanze di CluedoStart
	 */
	public static void testMain(String[] args){
		
		//va invocato prima della grafica
		lookAndFeel();
		
		System.out.println("SONO IL MAIN DI TEST");
		System.out.println("Utilizzo: CluedoStart <rmi-registry-host> <nickname>");
		System.out.println();
		// security manager
        if (System.getSecurityManager() == null) {
        	System.out.println("Installazione Security Manager");
            System.setSecurityManager(new SecurityManager());
        } else {
        	System.out.println("Security Manager gia' installato");
        }  

        // Lancia la CluedoStart senza creare il player
        //EventQueue.invokeLater(new Runnable() {public void run() {new CluedoStart();}});
        
        // Runnable di test
        EventQueue.invokeLater(new MyTestRunnable(args[0], Integer.parseInt(args[1]), args[2]) );
	}
	
	/** 
	 * Questo e' il metodo main() di "produzione"
	 * Entry Point di Cluedo.
	 * Utilizzo:
	 *      CluedoStart <rmi registry host>
	 */
	public static void cluedoMain(String[] args){
		
		// controllo gli argomenti
		String usage= "Utilizzo: CluedoStart <rmi registry host>\n";
		if (args.length!=1) {
			System.out.println(usage);
			System.exit(1);
		}
		
		String registryHost= args[0];
		
		//va invocato prima della grafica
		lookAndFeel();
		
		// security manager
        if (System.getSecurityManager() == null) {
        	System.out.println("Installazione Security Manager");
            System.setSecurityManager(new SecurityManager());
        } else {
        	System.out.println("Security Manager gia' installato");
        }        

		// Lancio della grafica
		EventQueue.invokeLater(new MyRunnable(registryHost));
	}
	
	
	/** Gestisce il Look and Feel */
	private static void lookAndFeel(){
		/*
		 * http://www.java2s.com/Tutorial/Java/0240__Swing/CustomizingaJListLookandFeel.htm
		 * http://www.java2s.com/Tutorial/Java/0240__Swing/CustomizingaJTabbedPaneLookandFeel.htm
		 * http://home.tiscali.nl/bmc88/java/sbook/061.html#list
		 * http://java2everyone.blogspot.it/2009/01/set-jbutton-gradient-color.html
		 * http://nadeausoftware.com/node/85
		 * // http://tips4java.wordpress.com/2008/10/09/uimanager-defaults/
		 */
		
		/*
		// Stampa tutti i defaults
		javax.swing.UIDefaults defaults = UIManager.getDefaults( );
		for (Map.Entry<Object, Object> entry : defaults.entrySet()) {
			System.out.println(entry);
		}
		*/
		
		
		try {
			// Imposta il L&F multi-piattaforma di Java ("Metal") con il tema di default (da Java SE 5) "Ocean" 
        UIManager.setLookAndFeel(
            UIManager.getCrossPlatformLookAndFeelClassName());
        MetalLookAndFeel.setCurrentTheme(new OceanTheme());
		} 
		catch (UnsupportedLookAndFeelException e) {
			System.err.println("CluedoStart: Non posso usare il look and feel specificato");		
		}
		catch (ClassNotFoundException e) {
			System.err.println("CluedoStart: Non e' possibile trovare la classe del look and feel specificato");	
		}
		catch (Exception e){
			System.err.println("L&F non impostato");
		}
	
		// GENERICI
		UIManager.put("OptionPane.background", new ColorUIResource(Color.BLACK));
		UIManager.put("OptionPane.messageForeground", new ColorUIResource(Color.LIGHT_GRAY));
		
		UIManager.put("Panel.background", new ColorUIResource(Color.BLACK));
		UIManager.put("Panel.foreground", new ColorUIResource(Color.LIGHT_GRAY));
		
		UIManager.put("Button.background", new ColorUIResource(Color.DARK_GRAY));
		UIManager.put("Button.foreground", new ColorUIResource(Color.LIGHT_GRAY));
		//UIManager.put("Button.border", BorderFactory.createLineBorder(Color.DARK_GRAY,2));
		LinkedList<Object> a=new LinkedList<Object>();
		a.add(0.35);
		a.add(0.2);
		a.add(new ColorUIResource(156,140,140));
		a.add(new ColorUIResource(40,0,0));
		a.add(new ColorUIResource(156,140,140));
		UIManager.put("Button.gradient", a);
		UIManager.put("Button.select", new ColorUIResource(40,0,0));
		UIManager.put("Button.focus", new ColorUIResource(Color.white));
		
		UIManager.put("Label.foreground", new ColorUIResource(Color.LIGHT_GRAY));
		
		UIManager.put("List.background", Color.LIGHT_GRAY);
		
		UIManager.put("TextArea.background", Color.LIGHT_GRAY);
		
		UIManager.put("TextPane.background", Color.LIGHT_GRAY);
		
		//JTabbedPane che contiene le carte
		UIManager.put("TabbedPane.selected", Color.GRAY); //colore casella selezionata
		UIManager.put("TabbedPane.selectHighlight", Color.WHITE);
		UIManager.put("TabbedPane.borderHightlightColor", Color.WHITE);
		UIManager.put("TabbedPane.foreground", Color.GRAY); //colore testo tab
		UIManager.put("TabbedPane.darkShadow",Color.WHITE);
		UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); //rimuovi bordi
		UIManager.put("TabbedPane.tabAreaInsets", new Insets(10, 20, 0, 0)); //sposto i tab piu' verso destra
		UIManager.put("TabbedPane.tabInsets", new Insets(15, 10, 10, 10));  //piu' spazio intorno al titolo del tab
		
	}
	
	/**
	 * Da un player (che quindi e' gia' registrato) crea e visualizza la finestra di 
	 * registrazione
	 * @wbp.parser.entryPoint
	 */
	public CluedoStart() {
		myPlayer= null;
		initialize();
	}
	
    /**
     * Nasconde (setVisible(false)) la finestra dei gruppi (aka finestra di registrazione,
     * aka finestra di selezione dei gruppi)
     */
    public void hideGroupWindow() {
    	/* 
    	 * Necessario non eliminare dalla memoria la finestra gruppi altrimenti viene 
		 * a mancare il riferimento per tornare dalla MainWindow alla finestra gruppi 
		 */
    	frame.setVisible(false);
    }
    
    /**
     * Chiude (dispose) la finestra dei gruppi (aka finestra di registrazione,
     * aka finestra di selezione dei gruppi)
     */
    public void closeGroupWindow() {
    	frame.setVisible(false);
		frame.dispose();
    }
    
    /**
     * Rende visibile la finestra dei gruppi (aka finestra di registrazione,
     * aka finestra di selezione dei gruppi)
     */
    public void showGroupWindow() {
    	frame.setVisible(true);
    }
    
	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		/*
		 * promemoria
		GridBagConstraints gbc_scrollPane1 = new GridBagConstraints();
		gbc_scrollPane1.gridx = 0;
		gbc_scrollPane1.gridy = 0;
		gbc_scrollPane1.widthx= 1;
		gbc_scrollPane1.widthy= 1;
		gbc_scrollPane1.fill = GridBagConstraints.BOTH;
		gbc_scrollPane1.ipadx= 0;
		gbc_scrollPane1.ipady= 0;
		gbc_scrollPane1.insets= new Insets(0, 0, 5, 0);
		gbc_scrollPane1.anchor = GridBagConstraints.NORTH;
		gbc_scrollPane1.weightx = 1.0;
		gbc_scrollPane1.weighty = 1.0;
		 */
		frame = new JFrame("The Amazing Cluedo!");

		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.setBounds(new Rectangle(600, 200));
		frame.setLocationRelativeTo(null); // al centro dello schermo
		frame.addWindowListener(new myWindowListener());

		JPanel contentPane = new JPanel();
		frame.setContentPane(contentPane);
		contentPane.setLayout(new GridLayout(1, 3, 10, 10)); // 3 colonne

		/* ****************************************************************** */
		// pannello con la lista dei gruppi (sinistra)
		
		JPanel groupListPane = new JPanel();
		contentPane.add(groupListPane);
		groupListPane.setLayout(new GridBagLayout());
		
		// etichetta
		JLabel groupsLabel= new JLabel("Gruppi di gioco");
		GridBagConstraints gbc_groupLabel = new GridBagConstraints();
		gbc_groupLabel.gridx = 0;
		//gbc_groupLabel.gridy = 0;
		gbc_groupLabel.fill = GridBagConstraints.HORIZONTAL;
		gbc_groupLabel.anchor = GridBagConstraints.NORTH;
		gbc_groupLabel.weightx = 1.0;
		gbc_groupLabel.insets= new Insets(5, 5, 5, 5);
		groupListPane.add(groupsLabel, gbc_groupLabel);
		
		// lista dei nomi dei gruppi
		groupListModel= new DefaultListModel();
		
		// jlist di groupListModel (con scroll pane
		JScrollPane scrollPane1 = new JScrollPane();
		GridBagConstraints gbc_scrollPane1 = new GridBagConstraints();
		gbc_scrollPane1.gridx = 0;
		//gbc_scrollPane1.gridy = 0;
		gbc_scrollPane1.fill = GridBagConstraints.BOTH;
		gbc_scrollPane1.anchor = GridBagConstraints.NORTH;
		gbc_scrollPane1.weightx = 1.0;
		gbc_scrollPane1.weighty = 1.0;
		groupListPane.add(scrollPane1, gbc_scrollPane1);
		// infine il jlist
		groupList = new JList(groupListModel);
		groupList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scrollPane1.setViewportView(groupList);
		
		// bottone "crea gruppo"
		btnCreateGroup = new JButton("Crea gruppo");
		btnCreateGroup.setToolTipText("Crea il tuo gruppo di gioco");
		GridBagConstraints gbc_btnCreateGroup = new GridBagConstraints();
		gbc_btnCreateGroup.gridx = 0;
		//gbc_btnCreateGroup.gridy = 1;
		gbc_btnCreateGroup.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnCreateGroup.anchor = GridBagConstraints.SOUTH;
		gbc_btnCreateGroup.weightx = 1.0;
		groupListPane.add(btnCreateGroup, gbc_btnCreateGroup);
		btnCreateGroup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// popup che chiede il nome del gruppo
				String name= JOptionPane.showInputDialog(frame, "Inserisci il nome del gruppo:");
				if ( (name!=null) && (name.equals("")) ) {
					JOptionPane.showMessageDialog(frame, "Nome non valido");
				} else if (name!=null) {
					
					if (myPlayer.addMyGroup(name)) {
						setGroupsPaneEnabled(false);
						setMembersPaneEnabled(true);
						setChatPaneEnabled(true);

						String str;
						str= "<html>Sei nel gruppo " + myPlayer.getMyPlayGroup() + "<br>" + 
								"Membri del gruppo: </html>";
						membersLabel.setText(str);						
					} else {
						// informo l'utente che il nome e' duplicato
						JOptionPane.showMessageDialog(frame, "Il nome \"" + name + "\" e' gia' stato usato.");
					}

				} // else (name==null) non faccio niente
			}
		});
		
		// bottone "unisciti al gruppo"
		btnJoinGroup = new JButton("Unisciti");
		btnJoinGroup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String sel= (String)groupList.getSelectedValue();
				if (sel!=null) {
					if (myPlayer.joinThatGroup(sel)) {
						setGroupsPaneEnabled(false);
						setMembersPaneEnabled(true);
						setChatPaneEnabled(true);

						String str;
						str= "<html>Sei nel gruppo " + myPlayer.getMyPlayGroup() + "<br>" + 
								"Membri del gruppo: </html>";
						membersLabel.setText(str);
					} else {
						JOptionPane.showMessageDialog(frame, 
								"Non e' possibile unirsi a questo gruppo:\n" +
								"gruppo pieno o partita gia' iniziata",
								myPlayer.getNickname(),
								JOptionPane.WARNING_MESSAGE);
					}
				}
			}
		});
		btnJoinGroup.setToolTipText("Unisciti al gruppo di gioco selezionato");
		GridBagConstraints gbc_btnJoinGroup = new GridBagConstraints();
		gbc_btnJoinGroup.gridx = 0;
		//gbc_btnJoinGroup.gridy = 2;
		gbc_btnJoinGroup.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnJoinGroup.anchor = GridBagConstraints.SOUTH;
		gbc_btnJoinGroup.weightx = 1.0;
		groupListPane.add(btnJoinGroup, gbc_btnJoinGroup);
		
		/* ****************************************************************** */
		// pannello con la lista dei membri del gruppo (centro)
		
		JPanel groupMembersPane = new JPanel();
		contentPane.add(groupMembersPane);
		GridBagLayout gbl_groupMembersPane = new GridBagLayout();
		groupMembersPane.setLayout(gbl_groupMembersPane);
		
		// etichetta
		membersLabel= new JLabel("<html>Entra in un gruppo<br>&nbsp;</html>");
		GridBagConstraints gbc_membersLabel = new GridBagConstraints();
		gbc_membersLabel.gridx = 0;
		//gbc_groupLabel.gridy = 0;
		gbc_membersLabel.fill = GridBagConstraints.HORIZONTAL;
		gbc_membersLabel.anchor = GridBagConstraints.NORTH;
		gbc_membersLabel.weightx = 1.0;
		gbc_membersLabel.insets= new Insets(5, 5, 5, 5);
		groupMembersPane.add(membersLabel, gbc_membersLabel);
		
		// lista dei nomi dei membri del gruppo di cui il player fa parte
		memberListModel= new DefaultListModel();
		
		// jlist con i membri del gruppo (con scroll pane)
		JScrollPane scrollPane2 = new JScrollPane();
		GridBagConstraints gbc_scrollPane2 = new GridBagConstraints();
		gbc_scrollPane2.gridx = 0;
		//gbc_scrollPane2.gridy = 0;
		gbc_scrollPane2.fill = GridBagConstraints.BOTH;
		gbc_scrollPane2.anchor = GridBagConstraints.NORTH;
		gbc_scrollPane2.weightx = 1.0;
		gbc_scrollPane2.weighty = 1.0;
		groupMembersPane.add(scrollPane2, gbc_scrollPane2);
		// ed infine il jlist
		memberList = new JList(memberListModel);
		memberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		scrollPane2.setViewportView(memberList);
		
		// bottone "lascia gruppo"
		btnLeaveGroup = new JButton("Lascia gruppo");
		btnLeaveGroup.setToolTipText("Lascia questo gruppo di gioco");
		GridBagConstraints gbc_btnLeaveGroup = new GridBagConstraints();
		gbc_btnLeaveGroup.gridx = 0;
		//gbc_btnLeaveGroup.gridy = 1;
		gbc_btnLeaveGroup.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnLeaveGroup.anchor = GridBagConstraints.SOUTH;
		gbc_btnLeaveGroup.weightx = 1.0;
		groupMembersPane.add(btnLeaveGroup, gbc_btnLeaveGroup);
		btnLeaveGroup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
					myPlayer.exitMyPlayGroup();
					membersLabel.setText("<html>Entra in un gruppo<br>&nbsp;</html>");
			}
		});
		
		// bottone "Inizia partita"
		btnStartPlay = new JButton("Inizia partita");
		btnStartPlay.setToolTipText("Inizia la partita");
		GridBagConstraints gbc_btnStartPlay = new GridBagConstraints();
		gbc_btnStartPlay.gridx = 0;
		//gbc_btnStartPlay.gridy = 2;
		gbc_btnStartPlay.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnStartPlay.anchor = GridBagConstraints.SOUTH;
		gbc_btnStartPlay.weightx = 1.0;
		groupMembersPane.add(btnStartPlay, gbc_btnStartPlay);
		btnStartPlay.setMultiClickThreshhold(1000); // 1 secondo di attesa tra la generazione di un click e l'altra
		btnStartPlay.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// inizia una partita
				if (!myPlayer.startPlay()) {
					JOptionPane.showMessageDialog(CluedoStart.this.frame, 
							"Manca il numero minimo (" +
							CommonConstants.MIN_PLAYERS +
							") per giocare.");
				}
			}
		});
		
		/* ****************************************************************** */
		// pannello di chat (destra)
		
		JPanel chatPane = new JPanel();
		contentPane.add(chatPane);
		chatPane.setLayout(new GridBagLayout());
		
		// etichetta
		JLabel chatLabel= new JLabel("Chat del gruppo");
		GridBagConstraints gbc_chatLabel = new GridBagConstraints();
		gbc_chatLabel.gridx = 0;
		//gbc_groupLabel.gridy = 0;
		gbc_chatLabel.fill = GridBagConstraints.HORIZONTAL;
		gbc_chatLabel.anchor = GridBagConstraints.NORTH;
		gbc_chatLabel.weightx = 1.0;
		gbc_chatLabel.insets= new Insets(5, 5, 5, 5);
		chatPane.add(chatLabel, gbc_chatLabel);
		
		// area di testo della chat
		JScrollPane scrollPane3 = new JScrollPane();
		GridBagConstraints gbc_scrollPane3 = new GridBagConstraints();
		gbc_scrollPane3.gridx = 0;
		//gbc_scrollPane3.gridy = 0;
		gbc_scrollPane3.gridwidth= 2;
		gbc_scrollPane3.fill = GridBagConstraints.BOTH;
		gbc_scrollPane3.anchor = GridBagConstraints.NORTH;
		gbc_scrollPane3.weightx = 1.0;
		gbc_scrollPane3.weighty = 1.0;
		chatPane.add(scrollPane3, gbc_scrollPane3);
		// infine il jtextpane
		textChatPane = new JTextPane();
		scrollPane3.setViewportView(textChatPane);
		
		// textfield per input chat
		txtInputChat = new JTextField();
		GridBagConstraints gbc_txtInputChat = new GridBagConstraints();
		gbc_txtInputChat.gridx = 0;
		//gbc_txtInputChat.gridy = 1;
		gbc_txtInputChat.gridwidth= 1;
		gbc_txtInputChat.fill = GridBagConstraints.BOTH;
		gbc_txtInputChat.anchor = GridBagConstraints.SOUTHWEST;
		gbc_txtInputChat.weightx= 1.0;
		chatPane.add(txtInputChat, gbc_txtInputChat);
		txtInputChat.setColumns(10);
		
		// pulsante "invia messaggio di chat"
		btnSendChatMsg = new JButton("Invia");
		btnSendChatMsg.setToolTipText("Invia ai membri del gruppo");
		frame.getRootPane().setDefaultButton(btnSendChatMsg);
		btnSendChatMsg.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// invia un messaggio di chat agli altri membri del gruppo
				// il messaggio viene visualizzato nella finestra dei gruppi (CluedoStart)
				
				
				String text=txtInputChat.getText();
				
				if(text.equals("")) return;
				
				
				txtInputChat.setText(""); // vuota il contenuto del campo di Input della chat
				
				// invio il msg a tutti gli altri
				
				myPlayer.multicastChatMessage(myPlayer.getNickname(),text);
			            
				
			}
		});
		GridBagConstraints gbc_btnSendChatMsg = new GridBagConstraints();
		gbc_btnSendChatMsg.gridx = 1;
		//gbc_btnSendChatMsg.gridy = 1;
		gbc_btnSendChatMsg.gridwidth= 1;
		gbc_btnSendChatMsg.anchor = GridBagConstraints.SOUTHEAST;
		chatPane.add(btnSendChatMsg, gbc_btnSendChatMsg);

		
		/* ****************************************************************** */
		// finito, visualizzo
		
		setGroupsPaneEnabled(true);
		setMembersPaneEnabled(false);
		setChatPaneEnabled(false);
		
		//frame.pack();
		showGroupWindow();
		
		
		/* ****************************************************************** */
	}
	
	/**
	 * Abilita o disabilita il pannello di visualizzazione dei gruppo
	 * @param enabled true per abilitare, false per disabilitare
	 */
	public void setGroupsPaneEnabled(boolean enabled) {
		groupList.setEnabled(enabled);
		btnCreateGroup.setEnabled(enabled);
		btnJoinGroup.setEnabled(enabled);
	}
	
	/**
	 * Abilita o disabilita il pannello di visualizzazione dei membri del gruppo
	 * @param enabled true per abilitare, false per disabilitare
	 */
	public void setMembersPaneEnabled(boolean enabled) {
		memberList.setEnabled(enabled);
		btnLeaveGroup.setEnabled(enabled);
		if (enabled) {
			boolean h= myPlayer.isGroupOwner();
			btnStartPlay.setEnabled(enabled && h);
		} else {
			btnStartPlay.setEnabled(false);
		}
		
		if (!enabled && (myPlayer==null || !myPlayer.isGroupMember()) ) {
			// ripulisco la lista dei membri del gruppo
			clearMemberList();
		}
	}
	
	/**
	 * Crea un'istanza di PawnSelection passandogli il frame della finestra
	 * di registrazione (di CluedoStart) e il player locale.
	 * Non viene visualizzata la finestra di selezione della pedina.
	 * @return la finestra di selezione pedina
	 */
	public PawnSelection createPawnSelectionDialog() {
		return new PawnSelection(frame, myPlayer);
	}
	
	/**
	 * Abilita o disabilita il pannello di visualizzazione di chat
	 * @param enabled true per abilitare, false per disabilitare
	 */
	public void setChatPaneEnabled(boolean enabled) {
		textChatPane.setEnabled(enabled);
		txtInputChat.setEnabled(enabled);
		btnSendChatMsg.setEnabled(enabled);
		if (!enabled) {
			textChatPane.setText("");
		}
	}
	
	/**
	 * Aggiunge un gruppo alla lista dei gruppi
	 * @param g nome del gruppo da aggiungere
	 */
	public void addGroup(String g) {
		groupListModel.addElement(g);
	}
	/**
	 * Rimuove un gruppo dalla lista dei gruppi
	 * @param g nome del gruppo da rimuovere
	 */
	public void delGroup(String g) {
		groupListModel.removeElement(g);
	}
	/**
	 * Ripulisce la lista dei gruppi
	 */
	public void clearGroupList() {
		groupListModel.clear();
	}
	
	/**
	 * Aggiunge un membro alla lista dei membri
	 * @param m nome del membro da aggiungere
	 */
	public void addMember(String m) {
		memberListModel.addElement(m);
	}
	/**
	 * Rimuove un membro alla lista dei membri
	 * @param m nome del membro da rimuovere
	 */
	public void delMember(String m) {
		memberListModel.removeElement(m);
	}
	/**
	 * Ripulisce la lista dei membri del gruppo
	 */
	public void clearMemberList() {
		memberListModel.clear();
	}
	

	/** Aggiorna la chat con il mio messaggio inviato o con un messaggio ricevuto 
	 *@param playerName il nickname del player che ha inviato il messaggio
	 *@param text il testo del messaggio 
	 */
	public void updateChat(String playerName, String text){
		
		if(text.compareTo("")==0) return;
		else text+="\n";
        StyledDocument doc = textChatPane.getStyledDocument();
        SimpleAttributeSet textStyle = new SimpleAttributeSet();
        SimpleAttributeSet nameStyle = new SimpleAttributeSet();
        SimpleAttributeSet timeStyle = new SimpleAttributeSet();
        
        SimpleDateFormat sDate = new SimpleDateFormat("HH:mm:ss");
        
        
        StyleConstants.setForeground(timeStyle,Color.BLACK);
        StyleConstants.setFontFamily(timeStyle,"Arial");
        StyleConstants.setFontSize(timeStyle, 11); // 14
        
        StyleConstants.setForeground(nameStyle, Color.BLACK);
        StyleConstants.setFontFamily(nameStyle,"Courier");
        StyleConstants.setFontSize(nameStyle, 11); // 20
        StyleConstants.setBold(nameStyle, true);
        
        StyleConstants.setForeground(textStyle ,Color.BLACK);
        StyleConstants.setFontFamily(textStyle ,"Arial");
        StyleConstants.setFontSize(textStyle , 11); // 18
        StyleConstants.setBold(textStyle , false);
        
        String tx="";
        String time="("+sDate.format(new Date())+") ";
        
        
        if(playerName.equals(myPlayer.getNickname())) {
        	tx="Io";
        	StyleConstants.setForeground(nameStyle, Color.RED);
        	StyleConstants.setForeground(textStyle ,Color.RED);
        	StyleConstants.setForeground(timeStyle,Color.RED);

        } else {
        	tx=playerName;
        }
       
        
        try{
        	doc.insertString(doc.getLength(),time,timeStyle);
        	doc.insertString(doc.getLength(), tx+": ",nameStyle);
        	doc.insertString(doc.getLength(),text,textStyle);
        	} catch(BadLocationException exc) {
        		exc.printStackTrace();
        	}
      
		
	}
	
	/**
	 * Classe di supporto
	 */
	private static class MyRunnable implements Runnable {
		  private String registryHost;

		  public MyRunnable(String registryHost) {
		    this.registryHost= registryHost;
		  }

		  public void run() {
			  Player player= null;
			  
			  try {
				  // inizializzazione e visualizzazione finestra
				  CluedoStart wind = new CluedoStart();
				  
				  CreatePlayerDialog playerDialog= new CreatePlayerDialog(wind.frame, registryHost, wind);
				  playerDialog.pack();
				  player= playerDialog.showAndGetPlayer();
				  if (player==null) {
					  // premuto annulla: uscita brutale
					  System.exit(1);
				  }

				  // tutto ok: copia le variabili locali negli attributi di classe
				  wind.myPlayer= player;
				  String h= wind.frame.getTitle();
				  wind.frame.setTitle(h + " - Ciao " + player.getNickname());
				  Player.log.print("Ciao, io sono \"" + player.getNickname() + "\"");
				  
			  } catch (Exception e) {
				  e.printStackTrace();
				  Player.log.printErr("Errore nell'apertura della CluedoStart");
				  System.exit(1);
			  }
		  }
	}
	
	/**
	 * TODO classe di test
	 */
	private static class MyTestRunnable implements Runnable {
		  private String registryHost;
		  private String nickname;
		  private Player player= null;
		  private CluedoStart wind;
		  private int pause= 500;
		  private int numPlayers; // numero di player che giocheranno
		  
		  public MyTestRunnable(String registryHost, int numPlayers, String nickname) {
		    this.registryHost= registryHost;
		    this.nickname= nickname;
		    this.numPlayers= numPlayers;
		  }

		  public void run() {
			  
			  try {
				  				  
				  if (nickname.equals("a")) {
					  play(1);
				  } else if (nickname.equals("b")) {
					  play(2);
				  } else if (nickname.equals("c")) {
					  play(3);
				  } else if (nickname.equals("d")) {
					  play(4);
				  } else if (nickname.equals("e")) {
					  play(5);
				  } else if (nickname.equals("f")) {
					  play(6);
				  } else {
					  System.err.println("Nickname non riconosciuto");
				  }
				  
			  } catch (Exception e) {
				  System.err.println("MyAutoRunnable");
				  e.printStackTrace();
				  System.exit(1);
			  }
		  }

		  private void addReg() throws RemoteException, NotBoundException, Exception {
			  wind = new CluedoStart();
			  
			  player= new Player(nickname, registryHost, wind);
			  boolean okReg=false;
			  
			  okReg=player.addRegistration();

			  if(!okReg){
				  System.err.println("Registrazione fallita, esco");
				  System.exit(1);
			  }
				  
			  // tutto ok: copia le variabili locali negli attributi di classe
			  wind.myPlayer= player;
			  String h= wind.frame.getTitle();
			  wind.frame.setTitle(h + " - Ciao " + nickname);
			  Player.log.print("Ciao, io sono \"" + nickname + "\"");
		  }
		  
		  private void play(int num) throws Exception {
			  if (num==1) {
				  addReg();
				  // primo player: proprietario
				  wind.frame.setLocation(700, 50);
				  // aggiungo gruppo
				  boolean okCreateGroup=false;
				  okCreateGroup=player.addMyGroup("ag");
				  
				  if(!okCreateGroup){ //non ho creato il mio gruppo
					  System.err.println("Creazione gruppo \"ag\" fallita, esco");
					  System.exit(1);
				  } 
					  
					  
				  wind.setGroupsPaneEnabled(false);
				  wind.setMembersPaneEnabled(true);
				  wind.setChatPaneEnabled(true);
				  // inizia partita
				  Thread.sleep((numPlayers+1)*pause);
				  //player.startPlay();
				  
			  } else if (num>1) {
				  Thread.sleep(pause);
				  addReg();
				  // altro player non proprietario
				  if (num<=3) {
					  wind.frame.setLocation(700, 50 + 250*(num-1)); // lato destro dello schermo
					  // unisciti al gruppo
					  Thread.sleep(pause*(num-1));
					  boolean joined =player.joinThatGroup("ag");
					  if(!joined){ //non mi sono aggiunto al gruppo
						  System.err.println("Aggiunta al gruppo \"ag\" fallita, esco");
						  System.exit(1);
					  } 
					  wind.setGroupsPaneEnabled(false);
					  wind.setMembersPaneEnabled(true);
					  wind.setChatPaneEnabled(true);
					  
				  } else { // num<=6
					  wind.frame.setLocation(20, 50 + 250*(num-4)); // lato sinistro dello schermo
					  // unisciti al gruppo
					  Thread.sleep(pause*(num-1));
					  boolean joined =player.joinThatGroup("ag");
					  if(!joined){ //non mi sono aggiunto al gruppo
						  System.err.println("Aggiunta al gruppo \"ag\" fallita, esco");
						  System.exit(1);
					  } 
					  wind.setGroupsPaneEnabled(false);
					  wind.setMembersPaneEnabled(true);
					  wind.setChatPaneEnabled(true);  
				  }
			  }
		  }
	}
	
	/**
	 * Listener per la gestione della chiusura della finestra
	 */
	private class myWindowListener implements WindowListener {
		
		@Override
		public void windowOpened(WindowEvent e) {}

		@Override
		public void windowClosing(WindowEvent e) {
			// gestisco la cancellazione della registrazione
			if (myPlayer!=null) {
				myPlayer.exit();
			}
		}

		@Override
		public void windowClosed(WindowEvent e) {}

		@Override
		public void windowIconified(WindowEvent e) {}

		@Override
		public void windowDeiconified(WindowEvent e) {}

		@Override
		public void windowActivated(WindowEvent e) {}

		@Override
		public void windowDeactivated(WindowEvent e) {}
		
	}
}
